package com.lby.redisdemo.rabbitmq;


import com.lby.redisdemo.bean.OrderBean;
import com.lby.redisdemo.constant.SimpleMqConstant;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 消费者
 *
 * @ClassName DirectSmsConsumer
 * @Description TODO
 * @Author louby0923
 * @Date 2023/5/30 14:52
 * @Version 1.0
 */
@Slf4j
@Component
public class DirectSmsConsumer {
    @Autowired

    private MongoTemplate mongoTemplate;
    private Map<String, Integer> counterMap = new ConcurrentHashMap<>();


    @Value("${spring.rabbitmq.listener.simple.retry.max-attempts}")
    private Integer maxAttempts;

    /**
     * 监听队列
     *
     * @param order   接收消息消息
     * @param channel 通道
     * @param message
     * @throws IOException
     */
    @RabbitHandler
    @RabbitListener(queues = {SimpleMqConstant.SMS_QUEUE})
    public void smsMessage(OrderBean order, Channel channel, Message message) throws IOException {
        Integer integer = counterMap.get(order.getRequestId());
        counterMap.put(order.getRequestId(), integer == null ? 1 : integer.intValue() + 1);

        try {
            log.info("sms direct --接收到消息：{}", order);
            int x = 1 / 0;
            mongoTemplate.save(order);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);

        } catch (Exception e) {
            if (counterMap.get(order.getRequestId()) >= maxAttempts) {
                //第三个false:失败不重回队列
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
                counterMap.remove(order.getRequestId());
            }
            log.error("消息即将再次返回队列处理...");
            // basicNack:表示失败确认，一般在消费消息业务异常时用到此方法，可以将消息重新投递入队列
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);


            /*if (message.getMessageProperties().getRedelivered()) {
                log.error("消息已重复处理失败,拒绝再次接收...");
                //basicReject: 拒绝消息，与basicNack区别在于不能进行批量操作，其他用法很相似 false表示消息不再重新进入队列
                //  channel.basicReject(message.getMessageProperties().getDeliveryTag(), false); // 拒绝消息
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
            } else {
                log.error("消息即将再次返回队列处理...");
                // basicNack:表示失败确认，一般在消费消息业务异常时用到此方法，可以将消息重新投递入队列
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            }*/
        }
    }
}
